/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "ui3D视口.h"

#include <core/引擎配置.h>
#include <basic_vec.h>

#include "底层绘图/intern/Vulkan/Vulkan框架.h"
#include "底层绘图/intern/Vulkan/buffer/Vk图像.h"
#include "底层绘图/底层绘图框架.h"
#include "场景/intern/S_Scene.h"
#include "物体/S_摄像机.h"
#include "UI/UI.h"

#include <thread>
#include <future>
#include <utility>
#include <time.h>



static float64 gdur;
static clock_t g时间start = clock();
static clock_t g时间end;



static std::set<C_3D视口*> g3D视口容器;


uint32 f_ui_3D视口添加渲染层(C_Widget* self, vec4 color, uint8 后期处理类型) {
	C_3D视口& box = *dynamic_cast<C_3D视口*>(self);

	auto* 渲染层 = f_surface3D_创建(box.m_Ctx3D, { 128, 128 }, E_MS次数::e_MS_1);

	渲染层->m_帧缓存->m_清除颜色 = color;
	渲染层->m_纹理绑定ID = box.m_UIctx->f_Bind_纹理(渲染层->m_Color[0]);
	渲染层->m_叠加类型 = 后期处理类型;

	box.m_渲染层.emplace_back(渲染层);
	return box.m_渲染层.size();
}

void f_ui_3D视口开启后期(C_Widget* self, bool 开启后期) {
	static_cast<C_3D视口*>(self)->m_绘制属性.m_开启后期 = 开启后期;
}

static void f_3D视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_3D视口& box = *dynamic_cast<C_3D视口*>(self);

	box.m_正在渲染 = false;
	box.m_镜头->f_set宽高比(self->m_Size);

	if (self->f_get窗口管理()->拖放状态 <= DEF_拖放状态_准备) {
		for (auto& e : box.m_渲染层) {
			f_surface3D_重置大小(e, _uVec2(self->m_Size));
		}
	
		//f_surface3D_重置大小(box.m_颜色渲染层, _uVec2(self->m_Size));
		//f_surface3D_重置大小(box.m_焦点渲染层, _uVec2(self->m_Size));

		if (box.m_绘制回调.mf_设置分辨率) {
			box.m_绘制回调.mf_设置分辨率(_uVec2(self->m_Size));
		}
	}
}

static void f_3D视口绘制(C_Widget* self, S_2D画布* 画布) {
	C_3D视口& box = *static_cast<C_3D视口*>(self);
	
	box.m_背景		= f_vg_genConvex((*self), *画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);
	box.m_纹理绘制	= f_vg_genTextures((*self), *画布, E_图层混合模式::e_Normal);
}

static void f_3D视口变换(C_Widget* self) {
	C_3D视口& box = *static_cast<C_3D视口*>(self);
	box.m_正在渲染 = true;

	std::vector<S_2DConvexRect>	区域(box.m_渲染层.size());
	std::vector<S_GPU内存块*>	形状(box.m_渲染层.size());
	std::vector<S_2D颜色包>		颜色(box.m_渲染层.size());
	std::vector<vec2>			位置(box.m_渲染层.size());
	
	uint32 index = 0;
	for (auto& e : box.m_渲染层) {
		
		形状[index] = box.m_图元形状;
		区域[index].offset = {};
		区域[index].size = self->m_Size;
		区域[index].radius = {1,1};
		区域[index].AA_type = { 0, e->m_纹理绑定ID };
		颜色[index].m_颜色 = {255,180,0,255};
		颜色[index].m_模式 = e->m_叠加类型;
		位置[index] = {};

		++index;
	}
	
	f_vg_setTextures(*box.m_纹理绘制, 区域.size(), 区域.data(), 形状.data());
	f_vg_tranform(*box.m_纹理绘制, 位置.size(), 位置.data());
	f_vg_color(*box.m_纹理绘制, 颜色.size(), 颜色.data());

	
	
	形状[0] = box.m_图元形状;
	区域[0].size = self->m_Size;
	区域[0].AA_type = { 1, 0 };
	颜色[0] = self->m_ColorA;
	位置[0] = {};

	f_vg_tranform(*box.m_背景, {});
	f_vg_drawConvex(*box.m_背景, 1, 形状.data(), 区域.data());
	f_vg_color(*box.m_背景, 1, 颜色.data());


	box.m_采样ID = 0;
	return;
}


C_3D视口::C_3D视口(S_UI渲染环境& ctx, S_设备环境& Ctx3D) : C_Widget(&ctx), m_Ctx3D(Ctx3D), m_Scene(nullptr), mf_场景外部更新回调(nullptr) {
	m_颜色A = S_UI主题::uic_灰色;
	m_绘制回调 = {};

	mf_布局 = f_3D视口布局;
	mf_绘制 = f_3D视口绘制;
	mf_变换 = f_3D视口变换;

	m_是否延展 = { true, true };

	_m_默认镜头 = f_ob_创建摄像机(Ctx3D);
	_m_默认镜头->f_set旋转(-20,-20,0);
	m_镜头 = _m_默认镜头;
	m_采样ID = 0;

	f_ui_3D视口添加渲染层(this, {0.5,0.6,0.7,1.0}, 0);
	
	f_widget_添加绘制画布(this);
	g3D视口容器.insert(this);
	return;




	auto& 采样器 = ctx.m_Mat->m_采样器;
	

	m_深度纹理 = f_tex_创建图像纹理(Ctx3D, { 512,512, 1 }, E_纹理格式::e_tf_R32, E_纹理维度类型::e_2D, e_MS_1);
	m_速度纹理 = f_tex_创建图像纹理(Ctx3D, { 512,512, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D, e_MS_1);
	m_历史纹理 = f_tex_创建图像纹理(Ctx3D, { 512,512, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D, e_MS_1);
	m_法线纹理 = f_tex_创建图像纹理(Ctx3D, { 512,512, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D, e_MS_1);

	f_tex_安装纹理采样器(m_深度纹理, 采样器);
	f_tex_安装纹理采样器(m_速度纹理, 采样器);
	f_tex_安装纹理采样器(m_历史纹理, 采样器);
	f_tex_安装纹理采样器(m_法线纹理, 采样器);


	m_正在渲染 = true;
	m_退出渲染 = false;
	m_渲染模式 = E_物体渲染模式::e_渲染模式_白模;
	m_调试层 = E_视口渲染调试层::e_渲染调试_合成;

	m_绘制属性.m_调试层方向 = 0;
	m_绘制属性.m_开启调试 = false;
	m_绘制属性.m_开启后期 = true;
	m_绘制属性.m_调试占比 = 0.5;
	m_绘制属性.m_渲染层ID = 0;
	m_绘制属性.m_调试层 = E_视口渲染调试层::e_渲染调试_合成;

	m_使用全局采样参数 = true;
	

	m_帧渲染参数.m_Frame = 0;
	m_帧渲染参数.m_ParallelLightNum = 0;
	m_帧渲染参数.m_SpotLightNum = 0;
	m_帧渲染参数.m_PointLightNum = 0;
	m_帧渲染参数.m_AreaLightNum = 0;
	m_帧渲染参数.m_BouncesNum = 4;
	m_帧渲染参数.m_LigthSamples = 4;
	m_帧渲染参数.m_SamplesNum = 32;
	m_帧渲染参数.m_world_ShaderID = -1;
	m_帧渲染参数.m_ViewOffset_X = 0;
	m_帧渲染参数.m_ViewOffset_Y = 0;
	m_帧渲染参数.m_MaxZ = 5000;
	m_帧渲染参数.m_OutLayer_PreviewMode = DEF_RF_PM_PreviewFlag | DEF_RF_PM_composite | 1;

	std::vector<S_着色器创建参数> 参数配置;
	参数配置 = {
		{ DEF_TasterTexturesBindID_r32ui, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ DEF_TasterTexturesBindID_rgba32ui, E_着色阶段::e_计算着色, E_板载缓存类型::e_图像缓存 },
		{ DEF_TasterBindID_AlphaListCount, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO },

		{ DEF_BINDING_Render_Image, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ DEF_ImageBindID_r_f32, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ 0, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ 2, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
	};

	const std::vector<S_常量推送创建参数> 常量 = {
		{E_着色阶段::e_计算着色, 0, sizeof(S_RenderDebug)},
	};

	m_后期深度混合 = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期透明混合.cspv", 参数配置);
	m_后期SMAA = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期SMAA.cspv", 参数配置);
	m_后期预览调试 = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期预览调试.cspv", 参数配置, 常量);
	
	参数配置 = {
		{ DEF_BINDING_Render_Image, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ DEF_ImageBindID_r_f32, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE_SAMPLER },
		{ 0, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE_SAMPLER },
		{ 2, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE_SAMPLER },
		{ 3, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE_SAMPLER },
	};
	m_后期TAA = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期TAA.cspv", 参数配置);
	m_后期FXAA = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期FXAA.cspv", 参数配置);



	参数配置 = {
		{ DEF_TasterTexturesBindID_r32ui, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
	};
	m_后期计算准备 = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期计算准备.cspv", 参数配置);
	f_df_init_GPU参数槽(&m_后期准备);
	f_df_allocGPU参数缓存槽(&m_后期准备, 1);


	
	参数配置 = {
		{ DEF_BINDING_Render_Image, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ DEF_ImageBindID_r_f32, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
		{ 0, E_着色阶段::e_计算着色, E_板载缓存类型::e_IMAGE },
	};
	m_后期焦点描边 = f_df_创建并行计算(Ctx3D, S_引擎配置::m_3D着色器文件根路径 + "后期焦点描边.cspv", 参数配置);
	f_df_init_GPU参数槽(&m_描边_参数布局);
	f_df_allocGPU参数缓存槽(&m_描边_参数布局, 3);

	f_df_init_GPU参数槽(&m_参数布局);
	f_df_allocGPU参数缓存槽(&m_参数布局, 7);

	f_df_init_GPU参数槽(&m_抗锯齿参数布局);
	f_df_allocGPU参数缓存槽(&m_抗锯齿参数布局, 5);

}

C_3D视口::~C_3D视口() {
	m_退出渲染 = true;

	m_线程.joinable();

	for (auto& e : m_渲染层) {
		m_UIctx->f_UpBind_纹理(e->m_Color[0]);
		f_surface_Release(e);
	}
	
	f_ob_销毁摄像机(m_镜头);

	g3D视口容器.erase(this);
}

bool C_3D视口::f_渲染() {
	
	vec2 视口大小 = {};
	vec2 视口偏移 = {};

	if (m_采样ID < DEF_UI_Sample_Num) {
		uint32 渲染层ID = 0;
		for (auto& e : m_渲染层) {
			if (_m_默认镜头 == m_镜头) {
				m_镜头->f_set宽高比(m_Size);
				视口大小 = _Vec2(e->m_帧缓存->m_Size);
			}
			else {

				float32 比例 = float32(m_镜头->m_分辨率.y) / float32(m_镜头->m_分辨率.x);
				if (m_Size.y >= m_Size.x * 比例) {
					视口大小.x = m_Size.x;
					视口大小.y = 视口大小.x * 比例;
				}
				else {
					视口大小.y = m_Size.y;
					视口大小.x = 视口大小.y * (float32(m_镜头->m_分辨率.x) / float32(m_镜头->m_分辨率.y));
				}


				if (m_Size.x > 视口大小.x) {
					视口偏移.x = (m_Size.x - 视口大小.x) * 0.5;
				}
				if (m_Size.y > 视口大小.y) {
					视口偏移.y = (m_Size.y - 视口大小.y) * 0.5;
				}

				m_镜头->f_set宽高比(视口大小);
			}


		
			m_镜头->f_采样偏移(m_采样ID, 视口大小);
			m_镜头->f_Update(nullptr);
			++m_采样ID;

			if (m_绘制回调.mf_渲染) {
				m_绘制属性.m_渲染层ID = 渲染层ID;

				f_ob_render_begin(m_Ctx3D, *m_镜头, *m_Ctx3D.m_绘图框架->m_场景渲染环境);
				f_Draw_Begin_帧缓存(m_Ctx3D, e->m_帧缓存, 0);

				S_Viewport 视口{ 视口偏移.x, 视口偏移.y, 视口大小.x, 视口大小.y, 0.0f, 1.0f };
				S_Rect2D   裁剪{ _iVec2(视口偏移), _uVec2(视口大小) + _uVec2(视口偏移) };
				f_ob_render_view(m_Ctx3D, 视口, 裁剪, nullptr);

				m_绘制回调.mf_渲染(m_镜头, m_绘制属性, m_绘制回调.m_视口标识符);

				f_Draw_end_帧缓存(m_Ctx3D);
			}
			
			++渲染层ID;
		}
	}
	//采样合成 
	return true;



	if (m_Scene) {
		if (S_光追后端::g_渲染状态) return false;

		if (mf_场景外部更新回调) mf_场景外部更新回调(this);

		uvec2 纹理区块大小 = (_uVec2(视口大小) + 32) / 32;

		m_Scene->f_Update(m_镜头);
		if (m_Scene->f_载入纹理() == false) return false;

		switch (m_渲染模式) {
			case E_物体渲染模式::e_渲染模式_光追: {
				if (m_Scene->m_光追后端 && m_Scene->m_光追后端->m_渲染) {
					
					f_scene_构建光追加速结构(m_Scene);
					f_world_更新输出纹理(m_Scene->m_默认渲染世界, _uVec2(视口大小), 1);


					m_帧渲染参数.m_ViewSize = _uVec2(视口大小);
					m_Scene->m_光追后端->m_瓦片大小 = _uVec2(视口大小);
					
					m_帧渲染参数.m_BouncesNum = m_Scene->m_光追后端->m_渲染器预览参数.反弹次数;
					m_帧渲染参数.m_SamplesNum = m_Scene->m_光追后端->m_渲染器预览参数.光采样;
					m_帧渲染参数.m_ViewOffset_X = 视口偏移.x;
					m_帧渲染参数.m_ViewOffset_Y = 视口偏移.y;
					m_帧渲染参数.m_SceneMask_ObMask = 0x7f;

					if (m_Scene->m_光追后端->m_mapPtr_渲染帧数据->m_Frame > m_帧渲染参数.m_SamplesNum) return false;
					//m_Scene->f_Ray准备渲染(m_镜头, m_帧渲染参数, *m_颜色渲染层->m_Color[0], m_Scene->m_默认渲染世界, 0);
					
				}
				break;
			}
			case E_物体渲染模式::e_渲染模式_光栅: {
				{
					f_buf_UI32_at(f_buf_getGlobal().g_透明链表计数) = 0;
					f_buf_UI32_at(f_buf_getGlobal().g_透明链表计数, 1) = 0;
					uint32 size = 视口大小.x * 视口大小.y * 6;
					f_buf_resize(f_buf_getGlobal().g_透明链表纹理, DEF_Max(f_buf_getGlobal().g_透明链表纹理->m_Size, size));
					f_tex_setSize(f_buf_getGlobal().g_透明链表头, { uint32(纹理区块大小.x * 32), uint32(纹理区块大小.y * 32) });


					m_后期准备.m_参数槽[0] = f_buf_getGlobal().g_透明链表头;
					m_后期准备.m_参数类型[0] = E_板载缓存类型::e_IMAGE;
					m_后期准备.m_绑定位置[0] = DEF_TasterTexturesBindID_r32ui;
					m_后期准备.m_绑定数量[0] = 1;
					f_df_upGPU计算参数(m_后期计算准备, m_后期准备);
					f_GPU_run计算(m_后期计算准备, { 纹理区块大小.x, 纹理区块大小.y, 1 }, nullptr, 0);
				}
				



				auto 渲染参数 = f_scene_开始渲染(m_Scene, m_镜头, 视口大小, 视口偏移);
				渲染参数.m_线管槽 = E_管线槽::e_颜色渲染;

				//f_Draw_Begin_帧缓存(*m_颜色渲染层->m_Ctx, m_颜色渲染层->m_帧缓存, m_颜色渲染层->m_交换ID);
				f_scene_渲染世界(m_Scene, 渲染参数);
				for (auto& e : m_Scene->m_物体set) {
					if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_轮廓边, true);
				}
				for (auto& e : m_Scene->m_物体set) {
					if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_光照, true);
				}
				//f_Draw_end_帧缓存(*m_颜色渲染层->m_Ctx);
				
				//break;
				if (m_绘制属性.m_开启后期) {
					m_参数布局.m_参数槽[0] = f_buf_getGlobal().g_透明链表头;
					m_参数布局.m_参数类型[0] = E_板载缓存类型::e_IMAGE;
					m_参数布局.m_绑定位置[0] = DEF_TasterTexturesBindID_r32ui;
					m_参数布局.m_绑定数量[0] = 1;

					m_参数布局.m_参数槽[1] = f_buf_getGlobal().g_透明链表纹理;
					m_参数布局.m_参数类型[1] = E_板载缓存类型::e_图像缓存;
					m_参数布局.m_绑定位置[1] = DEF_TasterTexturesBindID_rgba32ui;
					m_参数布局.m_绑定数量[1] = 1;

					m_参数布局.m_参数槽[2] = &f_buf_getGlobal().g_透明链表计数;
					m_参数布局.m_参数类型[2] = E_板载缓存类型::e_SSBO;
					m_参数布局.m_绑定位置[2] = DEF_TasterBindID_AlphaListCount;
					m_参数布局.m_绑定数量[2] = 1;

					//m_参数布局.m_参数槽[3] = m_颜色渲染层->m_Color[0];
					m_参数布局.m_参数类型[3] = E_板载缓存类型::e_IMAGE;
					m_参数布局.m_绑定位置[3] = DEF_BINDING_Render_Image;
					m_参数布局.m_绑定数量[3] = 1;

					m_参数布局.m_参数槽[4] = m_深度纹理;
					m_参数布局.m_参数类型[4] = E_板载缓存类型::e_IMAGE;
					m_参数布局.m_绑定位置[4] = DEF_ImageBindID_r_f32;
					m_参数布局.m_绑定数量[4] = 1;

					//m_参数布局.m_参数槽[5] = m_颜色渲染层->m_Color[2];
					m_参数布局.m_参数类型[5] = E_板载缓存类型::e_IMAGE;
					m_参数布局.m_绑定位置[5] = 0;
					m_参数布局.m_绑定数量[5] = 1;

					m_参数布局.m_参数槽[6] = m_法线纹理;
					m_参数布局.m_参数类型[6] = E_板载缓存类型::e_IMAGE;
					m_参数布局.m_绑定位置[6] = 2;
					m_参数布局.m_绑定数量[6] = 1;
					
					f_df_upGPU计算参数(m_后期深度混合, m_参数布局);
					f_GPU_run计算(m_后期深度混合, { uint32(视口大小.x), uint32(视口大小.y), 1 }, nullptr, 0);
					//break;

					//m_抗锯齿参数布局.m_参数槽[0] = m_颜色渲染层->m_Color[0];
					m_抗锯齿参数布局.m_参数类型[0] = E_板载缓存类型::e_IMAGE;
					m_抗锯齿参数布局.m_绑定位置[0] = DEF_BINDING_Render_Image;
					m_抗锯齿参数布局.m_绑定数量[0] = 1;

					m_抗锯齿参数布局.m_参数槽[1] = m_深度纹理;
					m_抗锯齿参数布局.m_参数类型[1] = E_板载缓存类型::e_IMAGE_SAMPLER;
					m_抗锯齿参数布局.m_绑定位置[1] = DEF_ImageBindID_r_f32;
					m_抗锯齿参数布局.m_绑定数量[1] = 1;

					//m_抗锯齿参数布局.m_参数槽[2] = m_颜色渲染层->m_Color[2];
					m_抗锯齿参数布局.m_参数类型[2] = E_板载缓存类型::e_IMAGE_SAMPLER;
					m_抗锯齿参数布局.m_绑定位置[2] = 0;
					m_抗锯齿参数布局.m_绑定数量[2] = 1;

					m_抗锯齿参数布局.m_参数槽[3] = m_速度纹理;
					m_抗锯齿参数布局.m_参数类型[3] = E_板载缓存类型::e_IMAGE_SAMPLER;
					m_抗锯齿参数布局.m_绑定位置[3] = 2;
					m_抗锯齿参数布局.m_绑定数量[3] = 1;

					m_抗锯齿参数布局.m_参数槽[4] = m_历史纹理;
					m_抗锯齿参数布局.m_参数类型[4] = E_板载缓存类型::e_IMAGE_SAMPLER;
					m_抗锯齿参数布局.m_绑定位置[4] = 3;
					m_抗锯齿参数布局.m_绑定数量[4] = 1;

					f_df_upGPU计算参数(m_后期FXAA, m_抗锯齿参数布局);
					f_GPU_run计算(m_后期FXAA, { uint32(纹理区块大小.x), uint32(纹理区块大小.y), 1 }, nullptr, 0);

				}
				break;
			}
			case E_物体渲染模式::e_渲染模式_外部 : {

				if (m_绘制回调.mf_阴影环境渲染) {
					auto 渲染参数 = f_scene_开始渲染(m_Scene, m_镜头, _Vec2(纹理区块大小 * 32), 视口偏移);
					渲染参数.m_线管槽 = E_管线槽::e_阴影渲染;

					m_镜头->m_GPU参数槽.m_参数槽[0] = 渲染参数.m_视图投影矩阵;
					m_镜头->m_GPU参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
					m_镜头->m_GPU参数槽.m_绑定位置[0] = 0;
					m_镜头->m_GPU参数槽.m_绑定数量[0] = 1;
					f_df_setGPU参数布局(m_Ctx3D.m_逻辑设备.设备, m_镜头->m_GPU参数槽);
				}


				auto 渲染参数 = f_scene_开始渲染(m_Scene, m_镜头, _Vec2(纹理区块大小 * 32), 视口偏移);
				渲染参数.m_线管槽 = E_管线槽::e_颜色渲染;

				m_镜头->m_GPU参数槽.m_参数槽[0] = 渲染参数.m_视图投影矩阵;
				m_镜头->m_GPU参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
				m_镜头->m_GPU参数槽.m_绑定位置[0] = 0;
				m_镜头->m_GPU参数槽.m_绑定数量[0] = 1;
				f_df_setGPU参数布局(m_Ctx3D.m_逻辑设备.设备, m_镜头->m_GPU参数槽);

				break;
			}
			default: {
				auto 渲染参数 = f_scene_开始渲染(m_Scene, m_镜头, 视口大小, 视口偏移);
				渲染参数.m_线管槽 = E_管线槽::e_颜色渲染;
			}
		}


		if (m_绘制属性.m_开启调试) {
			S_RenderDebug 调试;
			调试.ComparisonRatio = m_绘制属性.m_调试占比;
			调试.Dir = m_绘制属性.m_调试层方向;
			调试.Layer = m_绘制属性.m_调试层;
			调试.CameraDis = m_镜头->m_近远端.y - m_镜头->m_近远端.x;

			f_df_upGPU计算参数(m_后期预览调试, m_参数布局);
			f_GPU_run计算(m_后期预览调试, { uint32(视口大小.x), uint32(视口大小.y), 1 }, & 调试, sizeof(S_RenderDebug));
		}
		
	}
	return false;
}


C_Widget* f_ui_创建3D视口(S_Scene* scene, const vec2& size, S_UI渲染环境& ctx, S_设备环境& Ctx3D) {
	C_3D视口* w = new C_3D视口(ctx, Ctx3D);
	w->f_setSize(size);
	w->m_Scene = scene;
	w->m_TypeName = "3D视口";
	return w;
}

void f_ui_3D视口绑定场景更新回调(C_Widget* self, fp_Widget更新 func) {
	static_cast<C_3D视口*>(self)->mf_场景外部更新回调 = func;
}

S_摄像机* f_ui_get3D视口摄像机(C_Widget* self) {
	assert(dynamic_cast<C_3D视口*>(self));
	return ((C_3D视口*)self)->m_镜头;
}

void f_ui_set3D视口摄像机(C_Widget* self, S_摄像机* camera) {
	((C_3D视口*)self)->m_镜头 = camera;
	((C_3D视口*)self)->m_镜头->f_set宽高比(self->m_Size);
}

void f_ui_set3D视口默认摄像机(C_Widget* self) {
	((C_3D视口*)self)->m_镜头 = ((C_3D视口*)self)->_m_默认镜头;
	((C_3D视口*)self)->m_镜头->f_set宽高比(self->m_Size);
}

bool f_ui_set3D视口是否为默认摄像机(C_Widget* self) {
	if (((C_3D视口*)self)->m_镜头 == ((C_3D视口*)self)->_m_默认镜头) {
		return true;
	}
	return false;
}

void f_ui_3d视口清除颜色(C_Widget* self, const vec4& color, uint32 渲染层) {
	assert(dynamic_cast<C_3D视口*>(self));
	C_3D视口& view = *((C_3D视口*)self);

	view.m_渲染层[0]->m_帧缓存->m_清除颜色 = color;
}

GLSL_RenderFrame& f_ui_get3D视口渲染帧属性(C_Widget* self) {
	assert(dynamic_cast<C_3D视口*>(self));
	return ((C_3D视口*)self)->m_帧渲染参数;
}

S_3D视口属性& f_ui_get3D视口渲染属性(C_Widget* self) {
	return ((C_3D视口*)self)->m_绘制属性;
}

void f_ui_切换3D视口渲染模式(C_Widget* self, E_物体渲染模式 fb) {
	auto& view = *static_cast<C_3D视口*>(self);
	view.m_渲染模式 = fb;
}

void f_ui_绑定3D视口渲染回调(C_Widget* self, const S_渲染回调& call) {
	auto& view = *static_cast<C_3D视口*>(self);
	view.m_绘制回调 = call;

	if (call.mf_轮廓渲染) {
		
	}
}

void f_ui_3D视口设置采样(C_Widget* self, E_MS次数 采样) {
	auto& view = *static_cast<C_3D视口*>(self);
	//f_surface_set采样(view.m_颜色渲染层, 采样);
}

void f_ui_3D视口关闭渲染(C_Widget* self) {
	auto& box = *static_cast<C_3D视口*>(self);

	for (auto& e : box.m_渲染层) {
		box.m_UIctx->f_UpBind_纹理(e->m_Color[0]);
	}
	box.m_开启渲染 = false;
}

void f_ui_3D视口绘制到屏幕() {
	
	for (auto& e : g3D视口容器) {
		if(e->m_开启渲染) {
			e->f_渲染();
		}

		std::vector<S_Surface3D*>& gpuCtx = e->m_渲染层;
	}
	
}


